<template>
  <div
    ref="wrapRef"
    :class="canResize && 'resizeTable'"
    style="height: 100%"
    id="table-wrap"
  >
    <a-table
      :row-key="
        (record, index) => {
          return record.id || index;
        }
      "
      @resizeColumn="handleResizeColumn"
      v-bind="{ ...$props, ...$attrs }"
      :columns="columns"
      :data-source="data"
      :pagination="pageCon"
      :transform-cell-text="transformCellText"
      :row-selection="needSelect ? rowSelection : null"
      @change="tableChange"
      :scroll="{ x: 'calc(100%)', ...(canResize && { y: tableContentHei }) }"
    >
      <!--  自定义slots start-->
      <template v-for="(value, key) in $slots" #[key]="slotProps">
        <slot :name="key" v-bind="slotProps"></slot>
      </template>
    </a-table>
  </div>
</template>

<script setup>
import { isEmpty } from "@/utils/is";
import { debounce } from "@/utils/common";
import { nextTick, onMounted, onUnmounted, ref, unref, watch } from "vue";
import { cloneDeep } from "lodash";
const props = defineProps({
  columns: {
    type: Array,
    default: () => [],
  },
  dataSource: {
    type: Array,
    default: () => [],
  },
  // 请求数据接口
  apiFetch: {
    type: Function,
    default: null,
  },
  // 是否显示分页器
  noPagination: {
    default: false,
    type: Boolean,
  },
  // 是否自动计算
  canResize: {
    default: false,
    type: Boolean,
  },
  // 额外查询条件
  queryParams: {
    type: Object,
    default: () => {
      return {};
    },
  },
  // 自动refresTable
  immediate: {
    default: true,
    type: Boolean,
  },
  pageSize: {
    default: 10,
    type: [Number, String],
  },
  // 需要筛选
  needSelect: {
    default: false,
    type: Boolean,
  },
});
// 页码参数
const pageOptions = ref({
  current: 1,
  pageSize: props.pageSize,
  total: 0,
  size: "small",
  pageSizeOptions: ["10", "20", "30", "40", "50"],
  showQuickJumper: true,
  showSizeChanger: true, // 显示可改变每页数量
  showTotal: (total) => `共 ${total} 条`, // 显示总数,
  onChange: (current, pageSize) => {
    pageOptions.value.current = current;
    pageOptions.value.pageSize = pageSize;
  },
  onShowSizeChange: (current, pageSize) => {
    pageOptions.value.current = current;
    pageOptions.value.pageSize = pageSize;
  },
});

const tableChange = (...args) => {
  fetch();
  // emit('change', ...args);
};
const data = ref([]);

// 接口请求获取数据
const fetch = async () => {
  const { apiFetch, queryParams } = props;
  if (apiFetch) {
    try {
      if (props.noNeedPage) {
        apiFetch({
          ...queryParams,
        }).then((result) => {
          data.value = result.data?.items || result.data;
          // 加载完成触发
          // emit("on-loading");
        });
      } else {
        let pageParams = {};
        pageParams["current"] = pageOptions.value.current;
        pageParams["size"] = pageOptions.value.pageSize;

        let params = {
          ...pageParams,
          ...queryParams,
        };
        // 请求之前对数据操作
        const res = await apiFetch(params);
        console.log("res", res);
        // resultData.value = res;
        // 判断返回值是否为数组
        const isArrayResult = Array.isArray(res.data);

        let resultItems = isArrayResult ? res.data : res.data["records"];

        const resultTotal = isArrayResult ? 0 : Number(res.data["total"]);

        // 假如数据变少，导致总页数变少并小于当前选中页码，通过getPaginationRef获取到的页码是不正确的，需获取正确的页码再次执行
        if (resultTotal) {
          const currentTotalPage = Math.ceil(
            resultTotal / pageOptions.value.pageSize
          );
          if (pageOptions.value.current > currentTotalPage) {
            pageOptions.value.current = currentTotalPage;
            return fetch();
          }
        }
        console.log("resultItems", resultItems);
        // 表格数据赋值
        data.value = resultItems;
        // 表格总数
        pageOptions.value.total = resultTotal;
        // 计算table内容列表滚动高度
        calcTableHeight();
      }
    } catch (error) {
      // emit("fetch-error", error);
      data.value = [];
      pageOptions.value.total = 0;
    }
  }
};

// 刷新列表数据
// const refreshList = () => {
//   pageOptions.value.current = 1;
//   // saveParams();
//   fetch();
// };
const refreshTableData = () => {
  pageOptions.value.current = 1;
  fetch();
};

const pageCon = computed(() => {
  // return pageOptions.value.total <= 10 ? false : props.pagination ? pageOptions.value : false;
  if (props.noPagination === true) {
    return false;
  }
  if (pageOptions.value.total <= 10) {
    return false;
  }
  return !props.noNeedPage ? pageOptions.value : false;
  // return pageOptions.value;
});

watch(
  () => props.dataSource,
  () => {
    const { dataSource, apiFetch } = props;
    !apiFetch && dataSource && (data.value = dataSource) && calcTableHeight();
  },
  {
    immediate: true,
  }
);

const wrapRef = ref(null);
const tableContentHei = ref(0);
// 计算table内容列表滚动高度
function calcTableHeight() {
  if (!props.canResize) {
    return;
  }
  nextTick(() => {
    const hei = wrapRef.value.offsetHeight;
    const tableHeader = document.querySelector("#table-wrap .ant-table-header");
    console.log("tableHeader", tableHeader);
    const tablePagin = document.querySelector("#table-wrap .ant-pagination");
    const tablePaginStyle =
      tablePagin && window.getComputedStyle(tablePagin, null);
    const tableHeaderHei = tableHeader.offsetHeight;
    const tablePaginOccupiedHei =
      Math.ceil(parseInt(tablePaginStyle?.height || 0)) +
      Math.ceil(parseInt(tablePaginStyle?.marginTop || 0));
    tableContentHei.value = hei - tableHeaderHei - tablePaginOccupiedHei - 5; // 表格容器横向滚动条高度默认给5
  });
}

// 开启复选
const rowSelection = reactive({
  selectedRowKeys: [],
  selectedRows: [],
  onChange: (selectedRowKeys, selectedRows) => {
    rowSelection.selectedRowKeys = selectedRowKeys;
    rowSelection.selectedRows = selectedRows;
    emit("rowSelection", selectedRows);
  },
});
function handleResizeColumn(w, col) {
  console.log('w',w);
  col.width = w;
}
const debounceCalcTableHeight = debounce(() => {
  calcTableHeight();
}, 100);

onMounted(() => {
  props.immediate && fetch();
  window.addEventListener("resize", debounceCalcTableHeight);
});
onUnmounted(() => {
  window.removeEventListener("resize", debounceCalcTableHeight);
});

const changeData = (handlerData) => {
  data.value = cloneDeep(handlerData(data.value));
};

const transformCellText = ({ text }) => {
  return isEmpty(text) ? "--" : text;
};

defineExpose({
  refreshTableData,
  fetch,
  data,
  changeData,
});
</script>

<style lang="less" scoped>
.resizeTable {
  flex: 1;
  overflow: hidden;
}
</style>
